package main.test.SparkAPI.Baics.classApi

object testClass {


  /**
   * Represent real-world elments and their interactions
   * Design class-subclass relations
   * The concept of class is key to oop, and allows you to represent elements and interactions.
   * class , subclass and abstract classes enable you to group entities that have common shapes and behaviors.
   * if you are familiar with other object o p languages.
   *
   * you will find similarityes with scala concept of class.
   * Table 7.1 recaps the different types of classes scala can offer.
   * use class to represent your vending machine.自动售货机
   *
   */

  /**
   * Summary of types of classes in scala. match definition of most other oop lang.
   *
   *  class : a representation of elements of the same kind from the real world
   *  All its func have an impl
   *  subclass: inherits behaviors from another class.a class can have up
   *  to one superclass.
   *  Superclass:  WHOSE methods are inherited by on or more classes
   *  Abstract class:  one or more mehtods may be abstract (ie they do
   *  not have an impl.)
   */

  /**
   * Suppose a robot with a name in your app. One solution is
   * to define a class using keyword clas.
   *
   *
   */
  // Name is declared as an immutable value.
class Robot(val name:String = "Unknown") {
    // define method in class

    /**
     * You can declare functions in it to
     * define some behavior specific to the class. You can refer to a function defined in a class
     * as method.
     */
    def welcome(n:String) = s"Welcome $n! My name is $name"
  }

  //Italian and Eng robts
  class ItalianRobot(name:String) extends Robot(name){
    /**
     * You can declare functions in it to
     * define some behavior specific to the class. You can refer to a function defined in a class
     * as method.
     */
    override def welcome(n: String): String =
      s"Benvenuto $n! Il mio nome e' $name"
  }

  class EnglishRobt(name:String,country:String)
  extends Robot(name) {
    /**
     * You can declare functions in it to
     * define some behavior specific to the class. You can refer to a function defined in a class
     * as method.
     */
    override def welcome(n: String): String =
      s"Welcom $n, I am $name from the country of $country!"
  }



  //class without parameters
  class myfirstClass {}
  val ins1 = new myfirstClass
  class mysecondClass(para1:String = "defaultVal"){}

  private val clazz = new mysecondClass()

  class Coordinate(latitude: Double, longitude: Double)

  /**
   *  Create a class Person with a name of type String and an age of
   * type Int—defaulted to 0. Define a method called presentYourself, for the class Person;
   * it takes no parameters, and it returns a string to communicate the name and
   * age of a person. Create two instances and see what the presentYourself method
   * returns for each of them: Martin is 18, and Bob is 0 years old.
   */
  class MydefPerson(name:String,
                    age:Int = 0){
    def presentYourself(): String ={
      s"my name is $name, my age is $age"
    }

  }

  class Teacher(name:String,
                age:Int)
  extends MydefPerson(name, age)

  class Student(name:String,
                age:Int,
                ID:Long)
  extends MydefPerson(name, age){
    override def presentYourself(): String = super.presentYourself() +
      s", my ID is $ID"
  }
//Abstract class
abstract class ABCRobot(val name:String) {
  // define method in class

  /**
   * You can declare functions in it to
   * define some behavior specific to the class. You can refer to a function defined in a class
   * as method.
   */
  def welcome(n:String):String
}

  class myRobt(name:String)
  extends ABCRobot(name){
    override def welcome(n: String): String = {
      s"Hello, $n!, my name is $name"
    }
  }


  /**
   * Yor can create 2 instances of a robot called Tome and John BY USING keword
   * NEW FOLLWED by the class name and its paras.
   * To access the parameter name, you need to declare it as a value (or variable) in the class
   * declaration
   */
    val tom = new Robot("Tom")
    val John = new Robot("John")
    val sunMingHang = new myRobt("sunMingHang")

  def testRobot() = {
    println("hello world "+tom.name)
    println(sunMingHang.welcome("cults"))

  }

  def testMydefPersons(): Unit ={
    val martin = new MydefPerson("Martin", 18)
    val bob = new MydefPerson("Bob", 0)
    println(martin.presentYourself())
    println(bob.presentYourself())
  }

def testSubclass(): Unit ={
  val xiaoMing = new Teacher("xiaoMing", 33)
  val hanMei = new Student("HanMei", 34, 123)
  println(xiaoMing.presentYourself())
  println(hanMei.presentYourself())
}

  def testForSytax()={
    var x=2
//    val y = if (x == 1) { true } else { false }
    val y = if (x == 1)  true   else   false
    println(s"y is $y")
  }

  def main(args: Array[String]): Unit = {
    testRobot
    testMydefPersons
    testSubclass
    testForSytax
//    val p = new Robot
//    println(p.name)
//    println(
//      tom.welcome(John.name)
//    )



  }

}
